package com.ai.util.langdu;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import lombok.extern.java.Log;
import org.springframework.stereotype.Service;

import javax.speech.Central;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.speech.EngineException;
import javax.speech.EngineStateError;
import javax.speech.synthesis.Synthesizer;
import javax.speech.synthesis.SynthesizerModeDesc;
import javax.speech.synthesis.Voice;

/**
 * windwos 、 linux 语音合成
 *
 * @author houwenpeng
 */
@Log
@Service
public class TextToSpeech {

    private static final String OS = System.getProperty("os.name").toLowerCase();

    private static final int VOLUME = 100; // 音量 0-100
    private static final int RATE = 1;     // 语音朗读速度 -10 到 +10
    private static final int VOICE_INDEX = 1; // 声色索引，从 0 开始

    private static final Logger logger = Logger.getLogger(TextToSpeech.class.getName());
    // 静态代码块确保系统属性只设置一次
    static {
        System.setProperty("freetts.voices", "com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory");
        try {
            Central.registerEngineCentral("com.sun.speech.freetts.jsapi.FreeTTSEngineCentral");
        } catch (EngineException e) {
            logger.log(Level.SEVERE, "Failed to register engine central", e);
        }
    }
    private static final String VOICE_NAME = "kevin16";
    private static final Locale LOCALE = Locale.US;
    private static final String SYNTHESIZER_MODE = "FreeTTS en_US general synthesizer";


    /**
     *  语音合成器-windows\linux
     * @param text
     */
    public void speech(String text) {
        if (OS.contains("win")) {
            textToSpeechWindows(text);
        } else if (OS.contains("nix") || OS.contains("nux") || OS.contains("mac")) {
            textToSpeechLinux(text);
        } else {
            System.out.println("Unsupported operating system.");
        }
    }


    /**
     * Windows
     * @param text
     */
    private static void textToSpeechWindows(String text) {

        ActiveXComponent ax = null;
        try {
            // 创建语音对象，使用 SAPI
            ax = new ActiveXComponent("Sapi.SpVoice");
            Dispatch spVoice = ax.getObject();

//            // 获取语音列表
//            Dispatch voices = Dispatch.get(ax, "GetVoices").toDispatch();
//            // 假设我们要选择第 2 个语音，索引从 0 开始，你可以根据实际需求选择不同的语音
//            Dispatch voice = Dispatch.call(voices, "Item", new Variant(1)).toDispatch();
//            // 设置音色
//            ax.setProperty("Voice", voice);

            // 设置音量 0-100
            ax.setProperty("Volume", new Variant(100));
            // 设置语音朗读速度 -10 到 +10
            ax.setProperty("Rate", new Variant(1));
            // 执行朗读
            Dispatch.call(spVoice, "Speak", new Variant(text));

            spVoice.safeRelease();
            ax.safeRelease();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * linux
     */
    private static void textToSpeechLinux(String text) {
        if (text == null || text.trim().isEmpty()) {
            logger.log(Level.WARNING, "输入文本为空或无效");
            return;
        }

        try {
            logger.log(Level.INFO, "进入 -> 文本转换语音");

            SynthesizerModeDesc synthesizerModeDesc = new SynthesizerModeDesc(SYNTHESIZER_MODE, "general", LOCALE, null, null);
            Synthesizer synthesizer = Central.createSynthesizer(synthesizerModeDesc);

            if (synthesizer == null) {
                logger.log(Level.SEVERE, "Failed to create synthesizer.");
                return;
            }

            try {
                synthesizer.allocate();
                synthesizer.resume();

                Voice voice = new Voice(VOICE_NAME, Voice.GENDER_MALE, Voice.AGE_CHILD, null);
                synthesizer.getSynthesizerProperties().setVoice(voice);

                synthesizer.speakPlainText(text, null);
                logger.log(Level.INFO, "已开始 -> 文本转换语音.");

                synthesizer.waitEngineState(Synthesizer.QUEUE_EMPTY);
                logger.log(Level.INFO, "已完成 -> 文本转换语音.");
            } finally {
                synthesizer.deallocate();
            }

        } catch (EngineException | EngineStateError e) {
            logger.log(Level.SEVERE, "语音合成引擎错误: " + e.getMessage(), e);
        } catch (Exception e) {
            logger.log(Level.SEVERE, "发生异常: " + e.getMessage(), e);
        } finally {
            logger.log(Level.INFO, "退出 -> 文本转换语音");
        }
    }

}